package model

import (
	"database/sql"
	"fmt"
	"github.com/jmoiron/sqlx"
	"time"
	"zimuzu_cvn_web_api/config"
	"zimuzu_cvn_web_api/pkg/drive/db"
	"zimuzu_cvn_web_api/pkg/e"
	"zimuzu_cvn_web_api/pkg/errno"
)

type YtaRechargeLogResponse struct {
	Id         int64   `json:"id" db:"id"`
	Uid        int64   `json:"uid" db:"uid"`
	Status     int     `json:"status" db:"status"`
	Address    string  `json:"address" db:"address"`
	Cvn        float64 `json:"cvn" db:"cvn"`
	CvnPrice   float64 `json:"cvn_price" db:"cvn_price"`
	Yta        float64 `json:"yta" db:"yta"`
	YtaPrice   float64 `json:"yta_price" db:"yta_price"`
	CreateTime string  `json:"create_time" db:"create_time"`
}

type YtaRechargeLogDown struct {
	Id         int64     `json:"id" db:"id"`
	Uid        int64     `json:"uid" db:"uid"`
	Status     int       `json:"status" db:"status"`
	Address    string    `json:"address" db:"address"`
	Cvn        float64   `json:"cvn" db:"cvn"`
	CvnPrice   float64   `json:"cvn_price" db:"cvn_price"`
	Yta        float64   `json:"yta" db:"yta"`
	YtaPrice   float64   `json:"yta_price" db:"yta_price"`
	CreateTime time.Time `json:"create_time" db:"create_time"`
}

type DownExcelYtaRechargeLog struct {
	Uid        int64   `json:"uid" db:"uid"`
	Status     string  `json:"status" db:"status"`
	Address    string  `json:"address" db:"address"`
	Cvn        float64 `json:"cvn" db:"cvn"`
	CvnPrice   float64 `json:"cvn_price" db:"cvn_price"`
	Yta        float64 `json:"yta" db:"yta"`
	YtaPrice   float64 `json:"yta_price" db:"yta_price"`
	CreateTime string  `json:"create_time" db:"create_time"`
}

type RechargeListParams struct {
	PageParams
	Status    int    `form:"status" json:"status" db:"status"`
	Start     string `json:"start" form:"start"`
	End       string `json:"end" form:"end"`
	TargetUid int    `json:"targetUid" form:"targetUid"`
}

type RechargeListDownParams struct {
	Status    int    `form:"status" json:"status" db:"status"`
	Start     string `json:"start" form:"start"`
	End       string `json:"end" form:"end"`
	TargetUid int    `json:"targetUid" form:"targetUid"`
}

type RechargeSetParams struct {
	ID     int64 `form:"id" json:"id" db:"id"`
	Status int   `form:"status" json:"status" db:"status"`
}

type RechargeBatchSetParams struct {
	IDS    []int64 `form:"ids" json:"ids"`
	Status int     `form:"status" json:"status"`
}

// 获取YTA兑换记录
func GetYtaRechargeLogById(Id int64) (res YtaRechargeLogResponse, err error) {

	db := config.C.DB.DB
	err = sqlx.Get(db, &res, "SELECT uid,status,address,cvn,cvn_price,yta,yta_price,create_time"+
		" FROM mg_yta_recharge WHERE id = ? ", Id)
	if err != nil {
		return YtaRechargeLogResponse{}, err
	}
	return res, nil
}

// 获取Yta兑换记录
func GetYtaRechargeLog(uid int64, Page, per, Status int) (res []YtaRechargeLogResponse, total int, err error) {
	Start := (Page - 1) * per
	db := config.C.DB.DB
	if Status == 0 {
		err = sqlx.Get(db, &total, "SELECT count(*) FROM mg_yta_recharge WHERE uid= ?", uid)
		err = sqlx.Select(db, &res, "SELECT uid,status,address,cvn,cvn_price,yta,yta_price,create_time "+
			" FROM mg_yta_recharge WHERE uid = ? ORDER by create_time DESC LIMIT ?,?", uid, Start, per)
	} else {
		err = sqlx.Get(db, &total, "SELECT count(*) FROM mg_yta_recharge WHERE uid= ? AND `status` = ?", uid, Status)
		err = sqlx.Select(db, &res, "SELECT uid,status,address,cvn,cvn_price,yta,yta_price,create_time "+
			" FROM mg_yta_recharge WHERE uid = ? AND `status` = ? ORDER by create_time DESC LIMIT ?,?", uid, Status, Start, per)
	}
	if err != nil {
		if err == sql.ErrNoRows {
			return res, total, nil
		} else {
			return res, total, err
		}
	}
	return res, total, nil
}

// 新增Yta兑换记录
func AddYtaRechargeLog(db *db.TxLogger, params YtaRechargeLogResponse) (logId int64, err error) {
	r := sqlx.MustExec(db, "INSERT INTO mg_yta_recharge(uid,status,address,cvn,cvn_price,yta,yta_price)"+
		" VALUES (?,0,?,?,?,?,?) ", params.Uid, params.Address, params.Cvn, params.CvnPrice, params.Yta, params.YtaPrice)
	logId, err = r.LastInsertId()
	if err != nil {
		return logId, err
	}
	if logId <= 0 {
		return logId, errno.DbDataError
	}
	return logId, nil
}

// 更新Yta兑换记录状态
func UpdateYtaRechargeLog(db *db.TxLogger, Id int64, Status int) error {
	result, err := db.Exec("UPDATE mg_yta_recharge SET `status`=? WHERE id=?", Status, Id)
	if err != nil {
		e.Log("info", "更新Yta兑换记录状态 失败", err.Error())
		return err
	}
	lId, err := result.RowsAffected()
	if err != nil {
		e.Log("info", "更新Yta兑换记录状态 Lid=", lId, "&msg=", err.Error())
		return err
	}
	if lId <= 0 {
		return errno.DbDataError
	}
	e.Log("info", "更新Yta兑换记录状态 Lid=", lId)
	return nil
}

// 校验是否存在YTA地址
type UserYtaAddress struct {
	Id      int64  `json:"id" db:"id"`
	Status  int    `json:"status" db:"status"`
	Address string `json:"address" db:"address"`
}

func CheckUserYtaAddress(uid int64, address string) (UserAddress UserYtaAddress, err error) {
	db := config.C.DB.DB
	if address == "" {
		err = sqlx.Get(db, &UserAddress, "SELECT id,status,address FROM mg_yta_address WHERE uid = ?", uid)
	} else {
		err = sqlx.Get(db, &UserAddress, "SELECT id,status,address FROM mg_yta_address WHERE uid=? AND address=?", uid, address)
	}
	if err != nil {
		if err == sql.ErrNoRows {
			return UserAddress, nil
		} else {
			return UserAddress, err
		}
	}
	return UserAddress, nil
}

// 新增YTA地址
func AddYtaAddress(uid int64, address string) error {
	db := config.C.DB.DB
	var count int
	err := sqlx.Get(db, &count, "SELECT count(*) FROM mg_yta_address WHERE uid =?", uid)
	if err != nil {
		return err
	}
	if count > 0 {
		return errno.ExistsRecord
	}
	r := sqlx.MustExec(db, "INSERT INTO mg_yta_address(uid,address) VALUES (?,?) ", uid, address)
	lId, err := r.LastInsertId()
	if err != nil {
		return err
	}
	if lId <= 0 {
		return errno.DbDataError
	}
	return nil
}

// 修改YTA地址
func UpdateYtaAddress(Uid int64, address string) error {
	db := config.C.DB.DB
	r := sqlx.MustExec(db, "UPDATE mg_yta_address SET address=?, status=0 WHERE uid=? ", address, Uid)
	lId, err := r.RowsAffected()
	if err != nil {
		return err
	}
	if lId <= 0 {
		return errno.DbDataError
	}
	return nil
}

// 修改YTA地址 是否有效
func UpdateYtaAddressStatus(ID int64, Status int) error {
	db := config.C.DB.DB
	r := sqlx.MustExec(db, "UPDATE mg_yta_address SET status=? WHERE id=? ", Status, ID)
	lId, err := r.RowsAffected()
	if err != nil {
		return err
	}
	if lId <= 0 {
		return errno.DbDataError
	}
	return nil
}

// 查询YTA地址
type YtaAddressRes struct {
	Address string `json:"address" db:"address"`
	Status  int    `json:"status" db:"status"`
}

func GetYtaAddress(Uid int64) (Address YtaAddressRes, err error) {
	err = sqlx.Get(config.C.DB.DB, &Address, "SELECT address, status FROM mg_yta_address WHERE uid =? ", Uid)
	if err != nil {
		return Address, err
	}

	return Address, nil
}

type YtaAddressList struct {
	ID         int    `json:"id" db:"id"`
	Uid        int64  `json:"uid" db:"uid"`
	Address    string `json:"address" db:"address"`
	Status     int    `json:"status" db:"status"`
	CreateTime string `json:"create_time" db:"create_time"`
}

type YtaAddressDownList struct {
	ID         int       `json:"id" db:"id"`
	Uid        int64     `json:"uid" db:"uid"`
	Address    string    `json:"address" db:"address"`
	Status     int       `json:"status" db:"status"`
	CreateTime time.Time `json:"create_time" db:"create_time"`
}

type DownExcelYtaAddressList struct {
	Uid        int64  `json:"uid" db:"uid"`
	Address    string `json:"address" db:"address"`
	Status     string `json:"status" db:"status"`
	CreateTime string `json:"create_time" db:"create_time"`
}

type CoinPriceResponse struct {
	Code int    `json:"code"`
	Msg  string `json:"msg"`
	Data coinPriceData
}

type coinPriceData struct {
	Last float64 `json:"last"`
}

type CoinPriceShow struct {
	CVNT    float64 `json:"cvnt"`
	YTA     float64 `json:"yta"`
	Balance float64 `json:"balance"`
	Rate    float64 `json:"rate"`
	ToYta   float64 `json:"to_yta"`
}

// 获取地址列表总记录条数
func GetAdminYtaAddressListCount(db sqlx.Queryer, TargetUid, Status int, Start, End string) (qi int, err error) {
	sqlStr := fmt.Sprintf("SELECT count(*) FROM mg_yta_address WHERE create_time >= '%s' AND create_time <= '%s' ", Start, End)
	if Status >= 0 {
		//获取列表条目总数
		sqlStr += fmt.Sprintf("AND status = %d ", Status)
	}
	if TargetUid > 0 {
		sqlStr += fmt.Sprintf(" AND uid = %d ", TargetUid)
	}
	err = sqlx.Get(db, &qi, sqlStr)
	if err != nil {
		e.Log("err", err)
	}
	return qi, err
}

// 获取地址列表总记录条数
func GetAdminYtaAddressListData(db sqlx.Queryer, TargetUid, Status, StartLimit, EndLimit int, Start, End string) (qi []YtaAddressList, err error) {
	sqlStr := fmt.Sprintf("SELECT id,uid,address,status,create_time FROM mg_yta_address WHERE create_time >= '%s' AND create_time <= '%s' ", Start, End)
	if Status >= 0 {
		//获取列表条目总数
		sqlStr += fmt.Sprintf(" AND status = %d ", Status)
	}
	if TargetUid > 0 {
		sqlStr += fmt.Sprintf(" AND uid = %d ", TargetUid)
	}
	sqlStr += fmt.Sprintf(" ORDER BY create_time desc LIMIT %d, %d ", StartLimit, EndLimit)
	err = sqlx.Select(db, &qi, sqlStr)
	if err != nil {
		e.Log("err", err)
	}
	return qi, err
}

// 导出到Excel
func GetAdminYtaAddressListDataNoPage(db sqlx.Queryer, TargetUid, Status int, Start, End string) (qi []YtaAddressDownList, err error) {
	sqlStr := fmt.Sprintf("SELECT id,uid,address,status,create_time FROM mg_yta_address WHERE create_time >= '%s' AND create_time <= '%s' ", Start, End)
	if Status >= 0 {
		//获取列表条目总数
		sqlStr += fmt.Sprintf(" AND status = %d ", Status)
	}
	if TargetUid > 0 {
		sqlStr += fmt.Sprintf(" AND uid = %d ", TargetUid)
	}
	sqlStr += fmt.Sprintf(" ORDER BY create_time desc ")
	err = sqlx.Select(db, &qi, sqlStr)
	if err != nil {
		e.Log("err", err)
	}
	return qi, err
}

// 获取兑换列表总记录
func GetAdminYtaRechargeLogData(db sqlx.Queryer, TargetUid, Status, StartLimit, EndLimit int, Start, End string) (qi []YtaRechargeLogResponse, err error) {

	sqlStr := fmt.Sprintf("SELECT id,uid,status,address,cvn,cvn_price,yta,yta_price,create_time FROM mg_yta_recharge WHERE create_time >= '%s' AND create_time <= '%s' ", Start, End)
	if Status >= 0 {
		//获取列表条目总数
		sqlStr += fmt.Sprintf("AND status = %d ", Status)
	}
	if TargetUid > 0 {
		sqlStr += fmt.Sprintf(" AND uid = %d ", TargetUid)
	}
	sqlStr += fmt.Sprintf(" ORDER BY create_time desc LIMIT %d, %d ", StartLimit, EndLimit)
	err = sqlx.Select(db, &qi, sqlStr)
	if err != nil {
		e.Log("err", err)
	}
	return qi, err
}

// 导出到Excel
func GetAdminYtaRechargeLogDataNoPage(db sqlx.Queryer, TargetUid, Status int, Start, End string) (qi []YtaRechargeLogDown, err error) {
	sqlStr := fmt.Sprintf("SELECT uid,status,address,cvn,cvn_price,yta,yta_price,create_time FROM mg_yta_recharge WHERE create_time >= '%s' AND create_time <= '%s' ", Start, End)
	if Status >= 0 {
		//获取列表条目总数
		sqlStr += fmt.Sprintf("AND status = %d ", Status)
	}
	if TargetUid > 0 {
		sqlStr += fmt.Sprintf(" AND uid = %d ", TargetUid)
	}
	sqlStr += fmt.Sprintf(" ORDER BY create_time desc ")
	err = sqlx.Select(db, &qi, sqlStr)
	if err != nil {
		e.Log("err", err)
	}
	return qi, err
}

// 获取兑换列表总记录条数
func GetAdminYtaRechargeLogCount(db sqlx.Queryer, TargetUid, Status int, Start, End string) (qi int, err error) {
	sqlStr := fmt.Sprintf("SELECT count(*) FROM mg_yta_recharge WHERE create_time >= '%s' AND create_time <= '%s' ", Start, End)
	if Status >= 0 {
		//获取列表条目总数
		sqlStr += fmt.Sprintf("AND status = %d ", Status)
	}
	if TargetUid > 0 {
		sqlStr += fmt.Sprintf(" AND uid = %d ", TargetUid)
	}
	err = sqlx.Get(db, &qi, sqlStr)
	if err != nil {
		e.Log("err", err)
	}
	return qi, err
}
